glSimple("bgnpolygon", "glBegin(GL_POLYGON)", "special cases for polygons:#\tindependant quads: use GL_QUADS#\tindependent triangles: use GL_TRIANGLES"),
glSimple("endpolygon", "glEnd()"),
glSimple("pushmatrix", "glPushMatrix()"),
glSimple("popmatrix", "glPopMatrix()"),
glSimple("clear", "glClearIndex(index);glClearColor(r, g, b, a); glClear(GL_COLOR_BUFFER_BIT)", "clear: use only one of glCLearIndex or glClearColor,#and change index or r, g, b, a to correct values"),
glArgs("callobj", "glCallList($1)", "check list numbering"),
glArgs("charstr", "glCallLists(strlen($1), GL_UNSIGNED_BYTE, $1)", "charstr: check list numbering"), // XXX what list definitions need to be done before this works?
glArgs("cmov", "glRasterPos3f($1, $2, $3)"),
glArgs("cmov2", "glRasterPos2f($1, $2)"),
glArgs("cmov2i", "glRasterPos2i($1, $2)"),
glArgs("cmov2s", "glRasterPos2s($1, $2)"),
glArgs("cmovi", "glRasterPos3i($1, $2, $3)"),
glArgs("cmovs", "glRasterPos3s($1, $2, $3)"),
glArgs("color", "glIndexi($1)"),
glArgs("colorf", "glIndexf($1)"),
glArgs("setshade", "glIndexi($1)"),
glArgs("font", "glListBase(int n)", "see glListBase info"),
glArgs("getdepth", "{GLint get_depth_tmp[2];glGetIntegerv(GL_DEPTH_RANGE, get_depth_tmp);*($1)=get_depth_tmp[0];*($2)=get_depth_tmp[1];}", "You can probably do better than this."),
glArgs("smoothline", "if($1) glEnable(GL_LINE_SMOOTH); else glDisable(GL_LINE_SMOOTH)"), // args to smoothline?
glArgs("linesmooth", "if($1) glEnable(GL_LINE_SMOOTH); else glDisable(GL_LINE_SMOOTH)"), // args to linesmooth?
glArgs("callobj", "glCallList($1)", "check list numbering"),
glArgs("clipplane", "glClipPlane( GL_CLIP_PLANE0+($1), *equation); if($2) glEnable(GL_CLIP_PLANE+($1)); else glDisable(GL_CLIP_PLANE0+($1))", "see man page for glClipPlane equation"),
glArgs("cpack", "glColor4ubv(&($1))", "cpack: if argument is not a variable#might need to be:#\tglColor4b(($1)&0xff, ($1)>>8&0xff, ($1)>>16&0xff, ($1)>>24&0xff)"),
glArgs("crv", "glEvalCoord1f( u )", "replace u with domain coordinate"),
glArgs("crvn", "glEvalMesh1f(GL_LINE, 0, n-1 )", "replace n with domain coordinate index"),
glArgs("curvebasis", "glMap1();glMap2();glMapGrid()", "curvebasis: see man pages"),
glArgs("curveprecision", "glMap1();glMap2();glMapGrid()", "curveprecision:see man pages"),
glArgs("czclear", "glClearDepth($2);glClearColor(((float)(($1)&0xff))/255., (float)(($1)>>8&0xff)/255., (float)(($1)>>16&0xff)/255., (float)(($1)>>24&0xff)/255. );glClear(GL_DEPTH_BUFFER_BIT|GL_COLOR_BUFFER_BIT)", "change glClearDepth parameter to be in [0, 1]"),// pattern behavior?
glArgs("deflinestyle", "glNewList($1, GL_COMPILE);glLineStipple(factor, $2); glEndList()", "LineStipple:#\tget factor from lsrepeat()#\tYou don't really need to make a display list.#\tCheck list numbering."),
glArgs("setlinestyle", "if($1) {glCallList($1); glEnable(GL_LINE_STIPPLE);} else glDisable(GL_LINE_STIPPLE)", "setlinestyle: Check list numbering."),
glArgs("defpattern", "glNewList($1, GL_COMPILE); glPolygonStipple(MASK($3)); glEndList()", "glPolygonStipple:#\tSee man page to change $3 into mask.#\tYou don't really need to make a display list.#\tCheck list numbering."),
glArgs("defrasterfont", "glXUseXFont( font, first, count, listBase)", "glXUseFont: see man page"),
glArgs("draw", "glVertex3f($1, $2, $3)", "Add glEnd() after these vertices, before next glBegin()"),
glArgs("draw2", "glVertex2f($1, $2)","Add glEnd() after these vertices, before next glBegin()"),
glArgs("draw2i", "glVertex2i($1, $2)","Add glEnd() after these vertices, before next glBegin()"),
glArgs("draw2s", "glVertex2s($1, $2)","Add glEnd() after these vertices, before next glBegin()"),
glArgs("drawi", "glVertex3i($1, $2, $3)","Add glEnd() after these vertices, before next glBegin()"),
glArgs("draws", "glVertex3s($1, $2, $3)","Add glEnd() after these vertices, before next glBegin()"),
glArgs("move", "glBegin(GL_LINE_STRIP); glVertex3f($1, $2, $3)", "glBegin: Use GL_LINES if only one line segment is desired."),
glArgs("move2", "glBegin(GL_LINE_STRIP); glVertex2f($1, $2)", "glBegin: Use GL_LINES if only one line segment is desired."),
glArgs("move2i", "glBegin(GL_LINE_STRIP); glVertex2i($1, $2)", "glBegin: Use GL_LINES if only one line segment is desired."),
glArgs("move2s", "glBegin(GL_LINE_STRIP); glVertex2s($1, $2)", "glBegin: Use GL_LINES if only one line segment is desired."),
glArgs("movei", "glBegin(GL_LINE_STRIP); glVertex3i($1, $2, $3)", "glBegin: Use GL_LINES if only one line segment is desired."),
glArgs("moves", "glBegin(GL_LINE_STRIP); glVertex3s($1, $2, $3)", "glBegin: Use GL_LINES if only one line segment is desired."),
glArgs("getdisplaymode", "(glGetIntegerv(GL_INDEX_MODE, &dmtmp), dmtmp)", "get display mode:#\tHow to tell if doublebuffered?#\tYou can do better than this.#GLint dmtmp;"),
glArgs("getdrawmode", "glxGetCurrentContext()", "see man page"),
glArgs("getscrmask", "{ GLint tmp[4]; glGetIntegerv(GL_SCISSOR_BOX, &tmp);*($1)=tmp[0];*($2)=tmp[0]+tmp[2]-1;*($3)=tmp[1];*($4)=tmp[1]+tmp[3]-1;}", "get GL_SCISSOR_BOX:#You can probably do better than this."),
glArgs("getviewport", "{GLint tmp[4];glGetIntegerv(GL_VIEWPORT, &tmp);*($1)=tmp[0];*($2)=tmp[0]+tmp[2]-1;*($3)=tmp[1];*($4)=tmp[1]+tmp[3]-1;}", "get GL_VIEWPORT:#You can probably do better than this."),
glArgs("lrectread", "glReadPixels($1, $2, ($3)-($1)+1, ($4)-($2)+1, GL_RGBA, GL_BYTE, $5)", "lrectread: see man page for glReadPixels"),
glArgs("rectread", "glReadPixels($1, $2, ($3)-($1)+1, ($4)-($2)+1, GL_COLOR_INDEX, GL_SHORT, $5)", "rectread: see man page for glReadPixels"),
glArgs("lrectwrite", "glRasterPos2i($1, $2);glDrawPixels(($3)-($1)+1, ($4)-($2)+1, GL_RGBA, GL_BYTE, $5)", "lrectwrite: see man page for glDrawPixels"),
glArgs("rectwrite", "glRasterPos2i($1, $2);glDrawPixels(($3)-($1)+1, ($4)-($2)+1, GL_COLOR_INDEX, GL_SHORT, $5)", "rectwrite: see man page for glDrawPixels"),
glArgs("lsetdepth", "glDepthRange($1, $2)", "glDepthRange params must be scaled to [0, 1]"),
glArgs("setdepth", "glDepthRange($1, $2)", "glDepthRange params must be scaled to [0, 1]"),
glArgs("lsrepeat", "glLineStipple($1, pattern)", "lsrepeat: combine with pattern from deflinestyle"),
glArgs("getlsrepeat", "glGetIntegerv(GL_LINE_STIPPLE_REPEAT, &tmp)", "getlsrepeat: move tmp into your variable."),
glArgs("makeobj", "glNewList($1, GL_COMPILE)", "Check list numbering."),
glArgs("mapw", "gluProject(XXX)", "XXX I think this is backwards"),
glArgs("mapw2", "gluProject(XXX)", "XXX I think this is backwards"),
glArgs("pick", "glSelectBuffer($2, $1);glRenderMode(GL_SELECT);glMatrixMode(GL_PROJECTION);gluPickMatrix(x, y, w, h, viewport);glMatrixMode(GL_MODELVIEW)", "pick:#\tSelect buffer is type GLuint.#\tSet gluPickMatrix params.#See man pages.#\tMight want to push Projection matrix if you have endpick pop it."),
glArgs("picksize", "gluPickMatrix(x, y, $1, $2, viewport)", "picksize: merge this with other gluPickMatrix call due to pick()"),
glArgs("pixmode", "glPixelTransfer($1, $2)", "pixmode: see glPixelTransfer man page#Translate parameters."),
glArgs("pixmodef", "glPixelTransfer($1, $2)", "pixmodef: see glPixelTransfer man page#Translate parameters."),
glArgs("pnt", "glBegin(GL_POINTS);glVertex3f($1, $2, $3);glEnd()", "points: put as many vertices as possible between Begin and End"),
glArgs("pnti", "glBegin(GL_POINTS);glVertex3i($1, $2, $3);glEnd()", "points: put as many vertices as possible between Begin and End"),
glArgs("pnts", "glBegin(GL_POINTS);glVertex3s($1, $2, $3);glEnd()", "points: put as many vertices as possible between Begin and End"),
glArgs("pnt2", "glBegin(GL_POINTS);glVertex2f($1, $2);glEnd()", "points: put as many vertices as possible between Begin and End"),
glArgs("pnt2i", "glBegin(GL_POINTS);glVertex2i($1, $2);glEnd()", "points: put as many vertices as possible between Begin and End"),
glArgs("pnt2s", "glBegin(GL_POINTS);glVertex2s($1, $2);glEnd()", "points: put as many vertices as possible between Begin and End"),
glArgs("pwlcurve", "gluPwlCurve(*nobj, $1, $2, $3, $4)", "gluPwlCurve: replace nobj with your object#See man page"),
glArgs("rdr", "glVertex3f($1, $2, $3)", "Add glEnd() after these vertices, before next glBegin().#Relative drawing not supported -- change"),
glArgs("rdr2", "glVertex2f($1, $2)","Add glEnd() after these vertices, before next glBegin().#Relative drawing not supported -- change"),
glArgs("rdr2i", "glVertex2i($1, $2)","Add glEnd() after these vertices, before next glBegin().#Relative drawing not supported -- change"),
glArgs("rdr2s", "glVertex2s($1, $2)","Add glEnd() after these vertices, before next glBegin().#Relative drawing not supported -- change"),
glArgs("rdri", "glVertex3i($1, $2, $3)","Add glEnd() after these vertices, before next glBegin().#Relative drawing not supported -- change"),
glArgs("rdrs", "glVertex3s($1, $2, $3)","Add glEnd() after these vertices, before next glBegin().#Relative drawing not supported -- change"),
glArgs("readdisplay", "glReadPixels($1, $2, ($3)-($1)+1, ($4)-($2)+1, GL_RGBA, GL_BYTE, $5)", "readdisplay: see man page for glReadPixels"),
glArgs("readRGB", "{ int tmp[4]; glGetIntegerv(GL_CURRENT_RASTER_POS, tmp);glReadPixels(tmp[0], tmp[1], $1, 1, GL_RGBA, GL_BYTE, array);}", "readRGB: see man page for glReadPixels"),
glArgs("readpixels", "{ GLint tmp[4]; glGetIntegerv(GL_CURRENT_RASTER_POS, tmp);glReadPixels(tmp[0], tmp[1], $1, 1, GL_INDEX, GL_SHORT, $2);}", "readpixels: see man page for glReadPixels"),
glArgs("setnurbsproperty", "gluNurbsProperty(*nobj, $1, $2)", "Replace nobj with your object -- see man page"),
glArgs("setpattern", "if($1) {glCallList($1); glEnable(GL_POLYGON_STIPPLE);} else glDisable(GL_POLYGON_STIPPLE)", "pattern: check list numbering.#See substitutions made for defpattern.#see glPolygonStipple man page."),
glArgs("writepixels", "glDrawPixels($1, 1, GL_COLOR_INDEX, GL_SHORT, $2)", "writepixels: see man page for glDrawPixels"),
glArgs("writeRGB", "glDrawPixels($1, 1, GL_RGBA, GL_BYTE, PACK($2, $3, $4))", "writeRGB: see man page for glDrawPixels#\tYouhave to pack the arrays into RGBA"),
glArgs("getcmmode", "(glGetBooleanv(GL_INDEX_MODE, &tmp), tmp)", "getcmmode: multimap mode not supported.#long tmp;"),
glArgs("getcpos", "{ GLint cpostmp[4]; glGetIntegerv(GL_CURRENT_RASTER_POSITION, cpostmp); *($1) = cpostmp[0]; *($2) = cpostmp[1];}", "getcpos: You can probably do better than this."),
ostr = ostr.substr(1, ostr.length() - 2); // remove first and last " " added by read_line
cout << ostr << '\n';
if(debug)
cout.flush();
}
void
init_optional_functions()
{
if(!no_window) {
new glDelete("wintitle", "wintitle not supported -- See Window Manager");
new glDelete("winset", "winset not supported -- See Window Manager");
new glDelete("winpush", "winpush not supported -- See Window Manager");
new glDelete("winposition", "winposition not supported -- See Window Manager");
new glDelete("winpop", "winpop not supported -- See Window Manager");
new glDelete("winopen", "winopen not supported -- See Window Manager");
new glDelete("winmove", "winmove not supported -- See Window Manager");
new glDelete("winget", "winget not supported -- See Window Manager");
new glDelete("windepth", "windepth not supported -- See Window Manager");
new glDelete("winconstraints", "winconstraints not supported -- See Window Manager");
new glDelete("winclose", "winclose not supported -- See Window Manager");
new glDelete("videocmd", "videocmd not supported");
new glDelete("tpon", "tpon not supported");
new glDelete("tpoff", "tpoff not supported");
new glDelete("textport", "textport not supported");
new glDelete("textinit", "textinit not supported");
new glDelete("textcolor", "textcolor not supported -- See Fonts");
new glDelete("swinopen", "swinopen not supported -- See Window Manager");
new glDelete("stepunit", "stepunit not supported -- See Window Manager");
new glDelete("setvideo", "setvideo not supported");
new glDelete("setmonitor", "setmonitor not supported");
new glDelete("setmap", "setmap not supported -- See Window Manager");
new glDelete("setdblights", "setdblights not supported -- See Window Manager");
new glDelete("setbell", "setbell not supported -- See Window Manager");
new glDelete("scrnselect", "scrnselect not supported -- See Window Manager");
new glDelete("scrnattach", "scrnattach not supported -- See Window Manager");
new glDelete("screenspace", "screenspace not supported");
new glDelete("ringbell", "ringbell not supported -- See Window Manager");
new glDelete("reshapeviewport", "reshapeviewport not supported -- See Window Manager");
new glDelete("prefposition", "prefposition not supported -- See Window Manager");
new glDelete("prefsize", "prefsize not supported -- See Window Manager");
new glDelete("onemap", "onemap not supported -- See Window Manager");
new glDelete("noborder", "noborder not supported -- See Window Manager");
new glDelete("multimap", "multimap not supported -- See Window Manager?");
new glDelete("mswapbuffers", "mswapbuffers not supported -- See Window Manager");
new glDelete("mapcolor", "mapcolor not supported -- See Window Manager");
new glDelete("imakebackground", "imakebackground not supported -- See Window Manager");
new glDelete("icontitle", "icontitle not supported -- See Window Manager");
new glDelete("iconsize", "iconsize not supported -- See Window Manager");
new glDelete("greset", "greset not supported -- See Window Manager");
new glDelete("ginit", "ginit not supported -- See Window Manager");
new glDelete("gexit", "gexit not supported -- See Window Manager#\tThere's bound to be something you have to do!");
new glDelete("getwscrn", "getwscrn not supported -- See Window Manager");
new glDelete("getvideo", "getvideo not supported");
new glDelete("getsize", "getsize not supported -- See Window Manager");
new glDelete("getorigin", "getorigin not supported -- See Window Manager");
new glDelete("getmcolor", "getmcolor not supported -- See Window Manager");
new glDelete("getmonitor", "getmonitor not supported");
new glDelete("getmap", "getmap not supported");
new glDelete("getbutton", "getbutton not supported -- See Window Manager");
new glDelete("gammaramp", "gammaramp not supported");
new glDelete("fullscrn", "fullscrn not supported");
new glDelete("fudge", "fudge not supported");
new glDelete("endfullscrn", "endfullscrn not supported");
new glDelete("dglopen", "dglopen not supported");
new glDelete("dglclose", "dglclose not supported");
new glDelete("dbtext", "dbtext not supported, see Window Manager");
new glDelete("defcursor", "defcursor not supported, see Window Manager");
new glDelete("cyclemap", "cyclemap not supported, see Window Manager?");
new glDelete("curstype", "curstype not supported");
new glDelete("curson", "curson not supported");
new glDelete("cursoff", "cursoff not supported");
new glDelete("curorigin", "curorigin not supported");
new glDelete("blink", "blink not supported, see Window Manager");
new glDelete("blanktime", "blanktime not supported, see Window Manager");
new glDelete("blankscreen", "blankscreen not supported, see Window Manager");
new glDelete("winattach", "winattach obsolete -- see Window Manager");
new glDelete("setcursor", "setcursor not supported -- see Window Manager");
new glDelete("RGBcursor", "RGBcursor obsolete -- see Window Manager");
new glDelete("getcursor", "getcursor not supported -- see Window Manager?");
new glSimple("swapbuffers", "glXSwapBuffers(*display, window)", "swapbuffers: replace display and window");
new glSimple("singlebuffer", "glxChooseVisual(*dpy, screen, *attriblist)", "singlebuffer: don't use GLX_DOUBLEBUFFER in attriblist");
new glSimple("doublebuffer", "glxChooseVisual(*dpy, screen, *attriblist)", "doublebuffer: use GLX_DOUBLEBUFFER in attriblist");
new glSimple("cmode", "glxChooseVisual(*dpy, screen, *attriblist)", "cmode: use GLX_BUFFER_SIZE, 1024 in attriblist");
new glSimple("RGBmode", "glxChooseVisual(*dpy, screen, *attriblist)", "RGBmode: use GLX_RGBA in attriblist");
new glDelete("gbegin", "gbegin not supported -- See Window Manager");
new glDelete("getport", "getport obsolete -- see Window Manager");
new glDelete("keepaspect", "keepaspect not supported -- See Window Manager");
new glDelete("maxsize", "maxsize not supported -- See Window Manager");
new glDelete("minsize", "minsize not supported -- See Window Manager");
new glDelete("clkon", "clkon not supported");
new glDelete("clkoff", "clkoff not supported");
new glDelete("lampoff", "lampoff not supported -- See Window Manager");
new glDelete("lampon", "lampon not supported -- See Window Manager");
new glDelete("attachcursor", "attachcursor not supported -- See Window Manager");
}
if(!no_queue) {
new glDelete("blkqread", "blkqread not supported, see Events"); // XXX X equivalent?
new glDelete("getvaluator", "getvaluator not supported -- See Events");
new glDelete("isqueued", "isqueued not supported -- See Events");
new glDelete("noise", "noise not supported -- See Events");
new glDelete("qdevice", "qdevice not supported -- See Events");
new glDelete("qenter", "qenter not supported -- See Events");
new glDelete("qgetfd", "qgetfd not supported -- See Events");
new glDelete("qread", "qread not supported -- See Events");
new glDelete("qreset", "qreset not supported -- See Events");
new glDelete("qtest", "qtest not supported -- See Events");
new glDelete("setvaluator", "setvaluator not supported -- See Events");
new glDelete("tie", "tie not supported -- See Events");
new glDelete("unqdevice", "unqdevice not supported -- See Events");
new glDelete("unqdevice", "unqdevice not supported -- See Events");
new glDelete("getdev", "getdev not supported -- See Events");
new glDelete("qcontrol", "qcontrol not supported -- See Events");
}
if(!no_lighting) {
new glDefine("MAXLIGHTS", "(glGetIntegerv(GL_MAX_LIGHTS, &tmp), tmp)", "maxlights:#GLint tmp;");
new glDefine("MATERIAL", "GL_FRONT", "Use GL_FRONT in call to glMaterialf.");
new glDefine("BACKMATERIAL", "GL_BACK", "Use GL_BACK in call to glMaterialf.");
new glDefine("LIGHT7", "GL_LIGHT7");
new glDefine("LIGHT6", "GL_LIGHT6");
new glDefine("LIGHT5", "GL_LIGHT5");
new glDefine("LIGHT4", "GL_LIGHT4");
new glDefine("LIGHT3", "GL_LIGHT3");
new glDefine("LIGHT2", "GL_LIGHT2");
new glDefine("LIGHT1", "GL_LIGHT1");
new glDefine("LIGHT0", "GL_LIGHT0");
new glDefine("LMNULL", "");
new glDefine("TWOSIDE", "GL_LIGHT_MODEL_TWO_SIDE", "light model parameters need to be moved into a glLightModelf call.");
new glDefine("ATTENUATION2", "GL_QUADRATIC_ATTENUATION");
new glDefine("ATTENUATION", "GL_CONSTANT_ATTENUATION", "attenuation: see glLightf man page:#Add GL_LINEAR_ATTENUATION.");
new glDefine("LOCALVIEWER", "GL_LIGHT_MODEL_LOCAL_VIEWER", "light model parameters need to be moved into a glLightModelf call.");
new glDefine("SPOTLIGHT", "XXX_SPOTLIGHT", "see glLightf man page#Add GL_SPOT_EXPONENT and GL_SPOT_CUTOFF parameters.");
new glDefine("POSITION", "GL_POSITION");
new glDefine("LCOLOR", "GL_DIFFUSE", "light color: need to add GL_AMBIENT and GL_SPECULAR components.#ALPHA needs to be included in parameters.");
new glDefine("COLORINDEXES", "GL_COLOR_INDEXES");
new glDefine("ALPHA", "XXX_ALPHA", "alpha is to be included with other parameters");
new glDefine("SHININESS", "GL_SHININESS");
new glDefine("SPECULAR", "GL_SPECULAR", "include ALPHA parameter with specular");
new glDefine("DIFFUSE", "GL_DIFFUSE", "include ALPHA parameter with diffuse");
new glDefine("AMBIENT", "GL_AMBIENT", "Ambient:#\tIf this is a light model lmdef, then use glLightModelf and GL_LIGHT_MODEL_AMBIENT.#Include ALPHA parameter with ambient");
new glDefine("EMISSION", "GL_EMISSION", "include ALPHA parameter with emission");
new glDefine("SPOTDIRECTION", "GL_SPOT_DIRECTION");
new glArgs("lmdef", "glNewList($2, GL_COMPILE); glMaterialf(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, *$4); glEndList();", "lmdef other possibilities include:#\tglLightf(light, pname, *params);#\tglLightModelf(pname, param);#Check list numbering.#Translate params as needed.");
}
if(emulate_lighting) {
new glArgs("lmbind", "mylmbind($1, $2)"),
new glArgs("lmdef", "mylmdef($1, $2, $3, $4)");
}
}
int
main(int argc, char **argv)
{
options(argc, argv);
init_optional_functions();
while(read_line()) {
process_line();
print_line();
}
if(debug)
print_hits();
return errors;
}
/*
* return offset to matching parenthesis or quote characters
* returns 0 if none found.
* paren or quote must be first char.
*/
int matching(const char *in, int offset)
{
const char *s = &in[offset];
int r;
int c, m;
if(*s == '(')
m = ')';
else if(*s == '"')
m = '"';
else {
return 0;
}
s++;
while((c = *s)&& (c != m)) {
if(c == '(' && m != '"') { // don't look at stuff in quotes
if(!(r = matching(s)))
return 0;
s += r + 1;
} else if(c == '"') {
if(!(r = matching(s)))
return 0;
s += r + 1;
} else
s += 1;
}
if(!c || c != m)
return 0;
else
return s - &in[offset];
}
PerlStringList split_args( PerlString &in, int &ok)
{
PerlStringList results(10);
ok = 1;
int r = matching(in);
if(r == 0) { // no args possible
error( "un-matched parenthesis or quote");
ok = 0;
results.reset();
return results;
}
results.push("(");
PerlString s = in.substr(1, r-1); // get arg list without ()'s
PerlString rest = in.substr(r+1); // rest of input after ')'
int i = 0;
int j = 0;
int c;
while(i < s.length()) {
c = s[i];
if(c == '(' || c == '"') {
r = matching(s, i);
if(!r) {
error("un-matched paren or quote");
ok = 0;
results.reset();
break;
}
i += r + 1;
} else if(c == ',') {
results.push(s.substr(j, i-j));
i++;
j = i;
} else
i++;
}
results.push(s.substr(j, i-j));
results.push(")");
results.push(rest);
return results;
}
#if TEST_MATCH
main() {
PerlString istr;
do {
cin >> istr;
PerlStringList a = split_args (istr);
cout << a.join("\n") << '\n';
} while(!cin.eof());
}
#endif
// replace "$n" in input string with args[n] (1 based)
// $1 - $9, $a - $f, or $A - $F work
// no check is made for $<anything else> or $ at end of string!